package com.winit.openapi.apiadapter.controller.util;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import net.sf.json.JSONObject;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.winit.common.spi.SPIException;
import com.winit.common.spi.context.CommandContext;
import com.winit.openapi.constants.ApiConstant;
import com.winit.openapi.model.RequestMsg;
import com.winit.openapi.util.RequestUtil;

public class ApiClient {

    private static final Logger logger = LoggerFactory.getLogger(ApiClient.class);

    /**
     * 提供向AD的3E发送post请求的方法，注意JSONObject要使用net.sf下的，否则会认证失败
     * 
     * @param requestMsg
     * @param url
     * @return
     */
    public String postTo3E(RequestMsg requestMsg, String url) {
        String result = null;
        PostMethod post = null;
        try {
            String postData = JSONObject.fromObject(requestMsg).toString();
            StringRequestEntity entity = new StringRequestEntity(postData,
                ApiConstant.CONTENT_TYPE_JSON,
                ApiConstant.CHARSET_UTF8);

            post = new PostMethod(url);
            post.setRequestEntity(entity);

            HttpClient client = new HttpClient();
            CommandContext ctx = CommandContext.getContext();
            String sourceIp = ctx.get(ApiConstant.SOURCE_IP);
            post.setRequestHeader("x-forwarded-for", sourceIp);
            // 设置连接超时时间
            client.getHttpConnectionManager().getParams().setConnectionTimeout(60 * 1000);
            client.getHttpConnectionManager().getParams().setSoTimeout(60 * 1000);
            // client.getHttpConnectionManager().getParams().setParameter("REMOTE_ADDR",
            // sourceIp);
            int statusCode = client.executeMethod(post);

            if (statusCode == HttpStatus.SC_OK) {
                result = IOUtils.toString(post.getResponseBodyAsStream(), ApiConstant.CHARSET_UTF8);
            } else {
                throw new SPIException("Call API Interface Error: " + post.getStatusText());
            }
        } catch (Exception e) {
            logger.info("调用服务异常：" + e);
        } finally {
            if (post != null) {
                post.releaseConnection();// 会自动释放连接
            }
        }
        return result;
    }

    public String sendRequest(HttpServletRequest request, String url) {
        String method = request.getMethod();
        if (ApiConstant.METHOD_POST.equalsIgnoreCase(method)) {
            return sendPostRequest(request, url);
        } else if (ApiConstant.METHOD_GET.equalsIgnoreCase(method)) {
            return sendGetRequest(request, url);
        } else {
            logger.error("无法处理的请求方法：" + method);
        }
        return null;

    }

    /**
     * @param requestMsg
     * @param url
     * @return
     */
    private String sendPostRequest(HttpServletRequest request, String url) {
        String result = null;
        PostMethod post = null;
        try {
            String encoding = request.getCharacterEncoding();
            if (StringUtils.isBlank(encoding)) {
                encoding = ApiConstant.CHARSET_UTF8;
            }
            String inputStr = IOUtils.toString(request.getInputStream(), encoding);
            String contentType = request.getContentType();
            if (StringUtils.isBlank(inputStr)) {
                inputStr = (String) request.getAttribute(ApiConstant.SOURCE_INPUT_STRING);
            } else {
                // request里面的getInputStream只能读取一次，读取后保存在request中，后续取用
                request.setAttribute(ApiConstant.SOURCE_INPUT_STRING, inputStr);
            }
            if (StringUtils.isEmpty(inputStr)) {
                logger.error("请求URL：" + url + " 请求参数为空！");
                return null;
            }
            StringRequestEntity entity = new StringRequestEntity(inputStr, contentType, encoding);

            post = new PostMethod(url);
            post.setRequestEntity(entity);
            CommandContext ctx = CommandContext.getContext();
            String sourceIp = ctx.get(ApiConstant.SOURCE_IP);
            if (StringUtils.isBlank(sourceIp)) {
                sourceIp = RequestUtil.getIp(request);
            }
            post.setRequestHeader("x-forwarded-for", sourceIp);

            // 设置请求参数
            Map<String, String[]> params = request.getParameterMap();
            if (params != null) {
                HttpMethodParams para = new HttpMethodParams();
                for (Map.Entry<String, String[]> entry : params.entrySet()) {
                    para.setParameter(entry.getKey(), entry.getValue());
                }
                post.setParams(para);
            }

            HttpClient client = new HttpClient();
            // 设置连接超时时间
            client.getHttpConnectionManager().getParams().setConnectionTimeout(60 * 1000);
            client.getHttpConnectionManager().getParams().setSoTimeout(60 * 1000);
            int statusCode = client.executeMethod(post);
            // logger.info("请求URL：" + url + " 请求参数：\r" + inputStr);

            if (statusCode == HttpStatus.SC_OK) {
                result = IOUtils.toString(post.getResponseBodyAsStream(), encoding);
            }
        } catch (Exception e) {
            logger.error("调用服务异常,URL= " + url + " 异常为：" + e);
        } finally {
            if (post != null) {
                post.releaseConnection();// 会自动释放连接
            }
        }
        return result;
    }

    /**
     * @param requestMsg
     * @param url
     * @return
     */
    private String sendGetRequest(HttpServletRequest request, String url) {
        String result = null;
        GetMethod getMethod = null;
        try {
            String encoding = request.getCharacterEncoding();
            if (StringUtils.isBlank(encoding)) {
                encoding = ApiConstant.CHARSET_UTF8;
            }
            getMethod = new GetMethod(url);
            String queryString = request.getQueryString();
            getMethod.setQueryString(queryString);
            HttpClient client = new HttpClient();
            // 设置连接超时时间
            client.getHttpConnectionManager().getParams().setConnectionTimeout(60 * 1000);
            client.getHttpConnectionManager().getParams().setSoTimeout(60 * 1000);
            int statusCode = client.executeMethod(getMethod);

            if (statusCode == HttpStatus.SC_OK) {
                result = IOUtils.toString(getMethod.getResponseBodyAsStream(), encoding);
            }
        } catch (Exception e) {
            logger.error("调用服务异常,URL=" + url + " 异常为：" + e);
        } finally {
            if (getMethod != null) {
                getMethod.releaseConnection();// 会自动释放连接
            }
        }
        return result;
    }
}
